package com.panovue.dataextraction.reader;

import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.panovue.dataextraction.ReaderUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;

@Slf4j
public class AbcamReader extends AbstractReader {

    public AbcamReader() {
        super("abcam", true);
    }

    public AbcamReader(String key) {
        super("abcam", true);
        this.key = key;

        baseUrl = "https://www.abcam.cn/";
        baseDir += key + File.separator + "abcam" + File.separator;

        // 设置线程数
        setThreads(5);
        addSeedAndReturn(baseUrl + "products?keywords=" + key).type("list");

        getConf().setExecuteInterval(3000);

        buildDriver(true);

        // 开始爬取
        try {
            start(20);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void visit(Page page, CrawlDatums next) {
        data.set("应用类型", "");
        data.set("种属来源", "");
        data.set("反应种属", "");
        data.set("克隆属性", "");
        data.set("着色样式", "");
        data.set("稀释倍数", "");
        data.set("染色例图，对应的样本信息， 酸碱修复条件", "");
        data.set("参考文献情况", "");
    }

    @MatchType(types = "list")
    public void list(Page page, CrawlDatums next) {
        Element element = page.select(".search_results h3 a").first();
        String href = element.attr("href");
        next.addAndReturn(baseUrl + href).type("details");
    }

    @MatchType(types = "details")
    public void details(Page page, CrawlDatums next) {
        JSONObject details = new JSONObject();

        Elements main_info = page.select(".h4").parents().first().select("li");
        for (int i = 0; i < main_info.size(); i++) {
            String text = main_info.get(i).text();
            details.set(i + "", text);
        }
        data.set("主要特点和细节", details);

        Elements lis = page.select("h2:contains(概述)").parents().parents().first().select("ul").first().select("li");
        String describe = lis.select("h3:contains(描述)").parents().first().select("div.value").text();
        String host = lis.select("h3:contains(宿主)").parents().first().select("div.value").text();
        String testedApplication = lis.select("h3:contains(经测试应用)").parents().first().select("div.value").text();
        String speciesReactivity = lis.select("h3:contains(种属反应性)").parents().first().select("div.value").text();

        data.set("描述", describe);
        data.set("宿主", host);
        data.set("经测试应用", testedApplication);
        data.set("种属反应性", speciesReactivity);

        JSONObject application = new JSONObject();
        Elements trs = page.select("h2:contains(应用)").parents().select("table").first().select("tr");
        for (int i = 1; i < trs.size(); i++) {
            Elements tds = trs.get(i).select("td");
            String name = tds.get(0).text();
            String explain = tds.get(2).text();
            application.set(name, explain);
        }
        data.set("应用", application);

        String cellularLocalization = page.select("h2:contains(靶标)").parents().select("h3:contains(细胞定位)").parents().first().select(".value").text();

        data.set("细胞定位", cellularLocalization);

        JSONArray images_info = new JSONArray();
        Elements images = page.select(".images").select("li");
        for (Element image : images) {
            JSONObject image_info = new JSONObject();
            String id = image.attr("id");
            String image_url = image.select("a").first().attr("href");
            String description = image.select(".column.description").text();
            String image_caption = image.select(".column.image.gallery").text();
            ReaderUtil.saveFile(image_url, baseDir + "images" + File.separator + image_url.substring(image_url.lastIndexOf("/") + 1));
            image_info.set("name", id);
            image_info.set("image_url", image_url);
            image_info.set("description", description);
            image_info.set("image_caption", image_caption);
            images_info.add(image_info);

        }
        data.set("图像信息", images_info);

//        String product_code = page.select("#datasheet-header-container").attr("data-product-code");
//        next.addAndReturn("https://www.abcam.cn/DatasheetProperties/References?productcode=" + product_code).type("literatures");

        JSONArray literatures = new JSONArray();

        Elements li = page.select("#description_references").select("li");
        for (int i = 0; i < li.size(); i++) {
            JSONObject jsonObject = new JSONObject();
            Element element = li.get(i);
            String title = element.select("span").text();
            String url = element.select("a").attr("href");
            jsonObject.set("title", title);
            jsonObject.set("url", url);
            literatures.add(jsonObject);
        }
        data.set("文献",literatures);

    }

    @MatchType(types = "literatures")
    public void literatures(Page page, CrawlDatums next) {
        JSONArray literatures = new JSONArray();
        for (Object object : page.select("")) {
            JSONObject jsonObject = JSONUtil.parseObj(object);
            String title = jsonObject.getStr("Title");
            String url = "https://pubmed.ncbi.nlm.nih.gov/" + jsonObject.getInt("PubmedID");
            jsonObject.set(title, url);
            literatures.add(jsonObject);
        }
        data.set("文献",literatures);
    }
    @MatchCode(codes = {301, 302, 307})
    public void retry(Page page, CrawlDatums next) {
        CrawlDatum crawlDatum = new CrawlDatum();
        crawlDatum.url(page.location());
        crawlDatum.type(page.matchType("list") ? "list" : "details");
        crawlDatum.key(crawlDatum.getExecuteTime() + page.url());
        next.addAndReturn(crawlDatum);
    }

    @Override
    public void afterStop() {
        if (driver != null) {
            driver.quit();
        }
        FileUtil.writeUtf8String(data.toString(), baseDir + File.separator + key + ".json");
        log.info("abcam 数据爬取完成");
    }

    @Override
    public void execute(CrawlDatum datum, CrawlDatums next) throws Exception {
        super.execute(datum, next);
        log.info("url {} code {}", datum.url(), datum.code());
    }

    @Override
    public Reader buildReader(String key) {
        return new AbcamReader(key);
    }
}
